<?php
interface BillInterface {
	public function bill($accountId, $amout);
}


// 单个规则的时候，没有问题，如果规则增加，这里也会需要不断修改，容易出问题。需要将验证抽离


// class OrderProcessor {
// 	public function __construct(BillInterface $biller) {
// 		$this->biller = $biller;
// 	}

// 	public function process(Order $order) {
// 		// $recent = $this->getRecentOrderCount($order);
// 		$recent = $order->getRecentOrderCount($order->account);	//将职责放到对应的order中
// 		if ($recent > 0) {
// 			throw new \Exception('重复订单');
// 		}
// 		$this->biller->bill($order->account->id, $order->amount);
// 		Db::table('orders')->insert([
// 			'account' => $order->account->id,
// 			'amount' => $order->amount,
// 			'created_at' => Carbon::now()
// 		]);
// 	}

// 	// 职责不对，提取到新的类中
// 	protected function getRecentOrderCount(Order $order)
// 	{
// 		$timestamp = Carbon::now()->subMinutes(5);
// 		return Db::table('orders')
// 			->where('account', $order->account->id)
// 			->where('created_at', '>=', $timestamps)
// 			->count();
// 	}
// }

// 验证接口
interface OrderValidatorInterface {
	public function validate(Order $order);
}


//  订单重复验证类
class RecentOrderValidator implements OrderValidatorInterface {
	public function __construct(OrderRepository $orders) {
		$this->orders = $orders;
	}

	public function validate(Order $order) {
		$recent = $this->orders->getRecentOrderCount($order->account);
		if ($recent > 0) {
			throw new \Exception('订单重复');
		} 
	}
}

// 账号是否停用验证类
class SuspendAccountValidator implements OrderValidatorInterface {
	public function validate(Order $order)
	{
		if ($order->account->isSuspended()) {
			throw new \Exception('账号已停用');
		}
	}
}

class OrderProcessor {
	public function __construct(BillInterface $biller, OrderRepository $orders, array $validators = array()) {
		$this->biller = $biller;
		$this->orders = $orders;
		$this->validators = $validators;
	}

	public function process() {
		// 验证器数组遍历，进行验证即可
		foreach ($this->validators as $validator) {
			$validator->validate($this->orders);
		}
		$this->biller->bill($order->account->id, $order->amount);
		$this->orders->logOrder([
			'account' => $order->account->id,
			'amount' => $order->amount,
			'created_at' => Carbon::now()
		]];
	}
}